package com.gordon.wiki.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gordon.wiki.exception.BusinessException;
import com.gordon.wiki.exception.BusinessExceptionCode;
import com.gordon.wiki.pojo.User;
import com.gordon.wiki.req.UserLoginReq;
import com.gordon.wiki.req.UserQueryReq;
import com.gordon.wiki.req.UserResetPasswordReq;
import com.gordon.wiki.req.UserSaveReq;
import com.gordon.wiki.resp.PageResp;
import com.gordon.wiki.resp.UserLoginResp;
import com.gordon.wiki.resp.UserQueryResp;
import com.gordon.wiki.result.Result;
import com.gordon.wiki.result.ResultUtil;
import com.gordon.wiki.service.UserService;
import com.gordon.wiki.utils.CopyUtil;
import com.gordon.wiki.utils.SnowFlake;
import com.mysql.jdbc.log.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Projectname: wiki
 * @Filename: UserController
 * @Author: GordonLo
 * @Data:2022/11/17 16:58
 * @Description: TODO
 */
@RestController
@RequestMapping("/user")
public class UserController {

    private static final Logger LOG = LoggerFactory.getLogger(UserService.class);

    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private SnowFlake snowFlake;


    @GetMapping("/getUserListByPage")
    public Result getUserListByPage(@Valid UserQueryReq req) {
        Page<User> page = new Page<>(req.getPage(), req.getSize());

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (!ObjectUtils.isEmpty(req.getLogin_name())) {
            wrapper.eq("login_name", req.getLogin_name());
        }

        page = userService.page(page, wrapper);
        List<User> list = page.getRecords();

        LOG.info("总行数：{}", page.getTotal() + "");
        LOG.info("总页数：{}", page.getPages() + "");

        List<UserQueryResp> UserResps = CopyUtil.copyList(list, UserQueryResp.class);

        PageResp<UserQueryResp> respPage = new PageResp<>();
        respPage.setTotal(page.getTotal());
        respPage.setList(UserResps);

//        CommonResp<PageResp<UserQueryResp>> resp = new CommonResp<>();
//        resp.setContent(respPage);

        return ResultUtil.success(respPage);
    }

    //    @PostMapping("/save")
//    public Result save(@Valid @RequestBody UserSaveReq req){
//        User User = CopyUtil.copy(req, User.class);
//        userService.saveOrUpdate(User);
//
////        CommonResp resp = new CommonResp<>();
//        return ResultUtil.success();
//    }
    @PostMapping("/save")
    public Result save(@Valid @RequestBody UserSaveReq req) {
        User user = CopyUtil.copy(req, User.class);
        LOG.info(req.getPassword() + "-------------------");

//        CommonResp resp = new CommonResp<>();
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        LOG.info(user.getPassword() + "-------------------");
        //这里是修改
        if (user != null && user.getId() != null) {
            //虽然前端已经禁用修改登录名，但是还是要为防止黑客恶意修改，
            // 所以进入这里面将登录名置空，数据库该字段就不回去修改
            user.setLogin_name(null);
            user.setPassword(null);
            userService.saveOrUpdate(user);
            return ResultUtil.success();
        }
        //下面是新增  处理用户名唯一
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("login_name", req.getLogin_name());
        //根据用户名获取对象
        User userDB = userService.getOne(wrapper);
        if (userDB == null) {
            //没有重复就新增
            userService.saveOrUpdate(user);
        } else {
            //重复就报出自定义异常
            throw new BusinessException(BusinessExceptionCode.USER_LOGIN_NAME_EXIST);
        }

        return ResultUtil.success();
    }

    @GetMapping("/remove")
    public Result remove(int id) {

        userService.removeById(id);

//        CommonResp<Object> resp = new CommonResp<>();
        return ResultUtil.success();
    }


    @PostMapping("/resetPassword")
    public Result resetPassword(@Valid @RequestBody UserResetPasswordReq req) {

        User user = CopyUtil.copy(req, User.class);
        user.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()));
        userService.updateById(user);

//        CommonResp resp = new CommonResp<>();
        return ResultUtil.success();
    }

    @PostMapping("/userLogin")
    public Result userLogin(@Valid @RequestBody UserLoginReq req) {
        LOG.info(req.getPassword() + "-------------------");
//        CommonResp resp = new CommonResp<>();
        Result result = new Result();
        //根据用户名查出用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("login_name", req.getLogin_name());
        //根据用户名获取对象
        User userDB = userService.getOne(wrapper);
        if (ObjectUtils.isEmpty(userDB)) {
            //用户名不存在
            LOG.info("用户名不存在{}", req.getLogin_name());
            throw new BusinessException(BusinessExceptionCode.LOGIN_USER_ERROR);
//            return ResultUtil.failure();
        } else {
            //传递进来的也是经过两次加密的
//            if (userDB.getPassword().equals(req.getPassword())) {
            if (userDB.getPassword().equals(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()))) {
                //登录成功
                LOG.info(userDB.getPassword() + "-------------------");
                UserLoginResp userLoginResp = CopyUtil.copy(userDB, UserLoginResp.class);

                String token = String.valueOf(snowFlake.nextId());
                LOG.info("生成单点登录token：{}，并存入redis中", token);
                userLoginResp.setToken(token + "");
                redisTemplate.opsForValue().set(token, JSONObject.toJSONString(userLoginResp), 3600 * 24, TimeUnit.SECONDS);

                result.setData(userLoginResp);
                return ResultUtil.success(userLoginResp);
            } else {
                //密码不对
                LOG.info("密码不对，输入密码为{}", req.getPassword(), userDB.getPassword());
                throw new BusinessException(BusinessExceptionCode.LOGIN_USER_ERROR);
            }
        }
//        return ResultUtil.success();
    }

    @GetMapping("/logout/{token}")
    public Result logout(@PathVariable String token) {


        LOG.info("token-------------------" + token);

        redisTemplate.delete(token);
        LOG.info("从redis中删除token:{}", token);

//        CommonResp<Object> resp = new CommonResp<>();
        return ResultUtil.success();
    }

}
